const resolvePath = require('./paths')
const { DefinePlugin } = require('webpack')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const commonConfig = require('./webpack.common')
const { merge } = require('webpack-merge')
const TerserPlugin = require('terser-webpack-plugin')
const CompressionPlugin = require('compression-webpack-plugin')

//生产环境 配置参数！
const prodConfig = {
    mode: 'production',
    devtool: false,
    output: {
        filename: 'js/[name].[contenthash:8].js',
        // chunkFilename: 'js/chunk_[name].js',
        path: resolvePath('dist')
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2 // css文件中@import 往前推重新加载loader
                        }
                    },
                    'postcss-loader',
                    'less-loader'
                ]
            },
            {
                test: /\.(png|svg|gif|jpe?g)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            name: 'assets/[name].[contenthash:6].[ext]',
                            limit: 5 * 1024
                        }
                    }
                ]
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /.md$/,
                use: [
                    'html-loader',
                    './loaders/markdown-loader'
                ]
            },
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new DefinePlugin({ // index.html中的植入全局变量
            BASE_URL: '"./"' // 直接解析字符串后替换，所以需要外面再包一层
        }),
        new HtmlWebpackPlugin({ // index.html中的变量
            title: 'copyWebpackPlugin',
            template: './public/index.html'
        }),
        new MiniCssExtractPlugin({ // 生成额外css文件
            filename: 'css/[name].[contenthash:8].css' // dist/css 目录下
        }),
        new CompressionPlugin({ // 压缩gzip（需配合服务端配置支持gzip）
            test: /\.(css|js)$/,
            minRatio: 0.2 // 压缩比例默认0.8
        }),
        // 每次打包都会去执行，开发环境使用contentBase, v5.0 使用 static
        new CopyWebpackPlugin({
            patterns: [
                {
                    from: 'public',
                    globOptions: {
                        ignore: ['**/index.html'] // 忽略此文件，因为该文件由HtmlWebpackPlugin生成 注意，这里的**不能省，表示从public下面开始找，默认是从项目根路径
                    }
                }
            ]
        }),
    ],
    optimization: {
        chunkIds: 'named', // natural : 按使用顺序的数字 id , named : 对调试更友好的可读的 id , deterministic : 在不同的编译中不变的短数字 id。有益于长期缓存。在生产模式中会默认开启
        runtimeChunk: { // 提取公共runtime(import规则代码)
            name: 'runtime',
        },
        minimizer: [
            new TerserPlugin({ // 压缩js
                parallel: true,    //使用多进程并发运行
                extractComments: false, // 不创建licence文件
                terserOptions: {
                    output: {
                        comments: false
                    },
                    compress: {
                        pure_funcs: ['console.log', 'debugger']
                    }
                }
            })
        ],
        splitChunks: {
            chunks: 'initial', // async 处理异步 initial 处理同步 all
            name: false,
            minSize: 10000, // 如果拆分出来的包结果未达到该大小，则不拆分；结果超过该值则分包，单位B (生成 chunk 的最小体积（以 bytes 为单位）) default 20000
            // // maxSize: 50000, // 如果源代码未超过该大小的，则不拆分； 将源代码文件超过 maxSize 个字节的 chunk 分割成较小的部分 default 0
            // // minChunks: 1, // 被引用过多少次的才拆分
            cacheGroups: {
                // vue: {
                //     name: 'vue.min', // name不能使用占位符
                //     test: /[\\/]node_modules[\\/]vue[\\/]/,
                //     priority: -9 // 与vendors相同，则会被忽略，而打包到vendors包中
                // },
                axios: {
                    name: 'axios.min',
                    test: /[\\/]node_modules[\\/]axios[\\/]/,
                    priority: -9
                },
                default: {
                    filename: 'js/vendors_[contenthash:8].js',
                    // name: 'vendors11111',
                    // test: /[\\/]node_modules[\\/]/,
                    // reuseExistingChunk: true, // 复用其他chunk内已拥有的模块 当chunks引用了已经存在的被抽离的chunks时不会新创建一个chunk而是复用chunk
                    priority: -10 // 低于-10就会使name和filename无效
                },
            }
        }
    },
}

const config = merge(prodConfig, commonConfig)

module.exports = config